home *** CD-ROM | disk | FTP | other *** search
- /* video.c - a few video subroutines to make writing C programs
- a bit simpler
-
- a line of code for printing something will look like this:
-
- at(2,20); in(RED,WHITE); cprintf("Just Like English!");
-
- Of course, you can omit the at() or in() (or both) if you like.
-
- NOTE: Remember that you must somehow force VIDEO.C to recompile
- whenever you switch memory models. This is because I haven't
- specifically declared all the routines and variables as 'far'
- (I hate using extra space and code unless I have to). If you
- like, you can do so yourself, then you can link the same OBJ
- with any memory model.
-
- To use the following routines in your own program, just put the
- files video.c and video.hin your working directory,
- add the line '#include "video.h" to the top of your program, call
- initvideo() at the beginning of main(), and link video.obj with
- your main module.
-
- This has been tested, and runs without modification, on both
- Zortech C++ 1.0? and Turbo C 1.5. I don't know about other compilers
- or versions, but I imagine they shouldn't need much modification.
-
- As usual: permission granted to use this for whatever you want to,
- commercial, private, obscene, or otherwise.
-
- Laine Stump, 12/13/87
- */
- #include <stdarg.h>
- #include <stdio.h>
- #include <dos.h>
- #include <string.h>
- #include "video.h"
-
- typedef unsigned int WORD;
- typedef unsigned char BYTE;
-
- int curcolor;
- int currow, curcol;
- int scrrows, scrcols;
- WORD far *screen;
- char nibs[] = "0123456789ABCDEF";
-
- int screenrows(void) { return(scrrows); }
- int screencols(void) { return(scrcols); }
-
- void scroll(int lines, int x1, int y1, int x2, int y2)
- { /* Scrolls the screen between x1,y1 and x2,y2. Scrolling is up if
- lines is positive, down if it is negative */
- union REGS reg;
-
- if (lines < 0)
- {
- reg.h.ah = 7;
- lines = (-lines);
- }
- else
- reg.h.ah = 6;
- reg.h.al = lines;
- reg.h.bh = curcolor >> 8;
- reg.x.cx = (y1 << 8) + x1;
- reg.x.dx = (y2 << 8) + x2;
- int86(0x10, ®, ®);
- } /* scroll */
-
- void cursorsize(int startline, int endline)
- { /* Sets the size of the cursor */
- union REGS reg;
-
- reg.h.ah = 1;
- reg.x.cx = (startline << 8) + endline;
- int86(0x10, ®, ®);
- } /* cursorsize */
-
- void clearscreen(void)
- { /* clears the screen to curcolor and positions cursor at(0,0) */
- scroll(0, 0, 0, scrcols, scrrows);
- at(0,0);
- } /* clearscreen */
-
- void cleareol(void)
- { /* clears from current position to end of line */
- scroll(0,curcol, currow, scrcols, currow);
- }
-
- void at(int row, int col)
- { /* places the cursor at a specific row and column */
- union REGS reg;
-
- currow = row; curcol = col;
- reg.h.ah = 2;
- reg.h.bh = 0;
- reg.x.dx = (row << 8) + col;
- int86(0x10, ®, ®);
- } /* at */
-
- void in(char forecolor, char backcolor)
- { /* sets current color to 'color' */
- curcolor = (forecolor | (backcolor << 4)) << 8;
- } /* in */
-
- void cputc(char ch)
- {
- WORD far *ptr;
-
- *((WORD far *) (screen + (currow * scrcols) + curcol))
- = ch+curcolor;
- at(currow, curcol+1);
- } /* cputc */
-
- void cprintf(va_list arg_list, ...)
- /* Prints a string in video memory at current location in current color
- then advances cursor to end of string. This cprintf is functionally
- equivalent to the standard printf. the only difference is that it will
- use the color set by the function in(). (and that it is faster...)
- */
- {
- va_list arg_ptr;
- char *format;
- char output[81];
- BYTE* outptr;
- WORD far* scrptr;
- int ct, len;
-
- va_start(arg_ptr, arg_list);
- format = arg_list;
- vsprintf(output, format, arg_ptr);
- len = strlen(output);
- scrptr = screen + (currow * scrcols) + curcol;
- outptr = (BYTE *) output;
- for (ct = 0; ct < len; ct++)
- *scrptr++ = (*outptr++)+curcolor;
- at(currow,curcol+len);
- } /* cprintf */
-
- void Write16Bytes (void* buf)
- { /* write the 16 bytes at *buf as hex digits, followed by the
- ASCII equivalent of same, at the curent cursor location.
- This routine is a bit specialized to have in a general
- purpose library, but I wanted faster screen paints. That's
- one of the advantages of writing your own library - you get
- to change it! */
- int ct;
- BYTE* this;
- WORD far * scrptr;
-
- this = (BYTE *) buf;
- scrptr = (WORD far *) (screen + (currow * scrcols) + curcol);
- for(ct = 0; ct < 16; ct++)
- {
- *scrptr++ = nibs[(*(this)) >> 4]+curcolor;
- *scrptr++ = nibs[(*this++) & 0x0F]+curcolor;
- scrptr++;
- }
- this = buf;
- for(ct = 0; ct < 16; ct++)
- *scrptr++ = curcolor
- + (*this > 0x1F ? *(this++) : (*(this++),'.'));
- at(currow,curcol+65);
- } /* Write16Bytes */
-
- void initvideo(void)
- { /* this should be called once at the beginning of the application */
- union REGS reg;
- reg.h.ah = 15;
- int86(0x10, ®, ®);
- scrcols = reg.h.ah;
- scrrows = *((BYTE far *) MK_FP(0x0040,0x0084))+1;
- if (scrrows < 25) scrrows = 25;
- screen = (WORD far *)((reg.h.al != 7) ? 0xB8000000L : 0xB0000000L);
- in(LIGHTGRAY,BLACK); clearscreen();
- } /* initvideo */
-
- /*---- end of video.c ----*/
-